package com.sojson.util.qrcode;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.springframework.core.io.ClassPathResource;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.sojson.constant.Constant;
import com.sojson.util.StringUtil;
import com.sojson.util.cache.CacheUtil;
import com.sojson.util.file.FileUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 二维码工具类
 * 
 * @author liu
 * @date 2020-10-14
 */
@Slf4j
@SuppressWarnings("unused")
public class QrCodeUtil {

    /** 二维码内容颜色 */
    private static final int QR_COLOR = 0xFF000000;
    /** 二维码背景颜色 */
    private static final int QR_BGCOLOR = 0xFFFFFFFF;
    /** 二维码边框宽度 */
    private static final int QR_BORDER_WIDTH = 1;
    /** 二维码宽度 */
    private static final int QR_WIDTH = 400;
    /** 二维码高度 */
    private static final int QR_HEIGHT = 400;
    /** logo宽度在二维码中的比值(0-100) */
    private static final int QR_LOGO_RATIO_WIDTH = 33;
    /** logo高度在二维码中的比值(0-100) */
    private static final int QR_LOGO_RATIO_HEIGHT = 33;
    /** 二维码logo图片路径在缓存中的Key */
    private static final String LOGO_CACHE_PREFIX = Constant.PROPERTIES.getProperty("so.cache.qrCode.prefix");
    /** 二维码logo图片在本地的路径 */
    private static final String LOGO_IMAGE_PATH = "static/image/qrcode/100100.png";
    /** 二维码logo图片 */
    private static byte[] logo;

    static {
        try {
            String string = get(LOGO_CACHE_PREFIX);
            // if (StringUtils.isNotBlankObject(string)) {
            // logo = downloadGetBytesByLongFileSystem(string);
            // }

            if (isBlankObject(logo)) {
                logo = inputStreamToByte(new ClassPathResource(LOGO_IMAGE_PATH).getInputStream());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImageBase(String data) throws Exception {
        return getBufferedImageBase(data, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BORDER_WIDTH);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageBaseAndTitle(String data, String title) throws Exception {
        return getBufferedImageBaseAndTitle(data, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImageBase(String data, int width, int height) throws Exception {
        return getBufferedImageBase(data, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageBaseAndTitle(String data, int width, int height, String title)
        throws Exception {
        return getBufferedImageBaseAndTitle(data, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImageBaseAndColor(String data, int qrColor, int qrBgColor)
        throws Exception {
        return getBufferedImageBase(data, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageBaseAndTitleAndColor(String data, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getBufferedImageBaseAndTitle(data, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImageBase(String data, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        MultiFormatWriter multiFormatWriter = null;
        BitMatrix bm = null;
        BufferedImage image = null;
        multiFormatWriter = new MultiFormatWriter();

        // 参数顺序分别为：编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
        bm = multiFormatWriter.encode(data, BarcodeFormat.QR_CODE, width, height, getDecodeHintType());
        int w = bm.getWidth();
        int h = bm.getHeight();
        image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

        // 开始利用二维码数据创建Bitmap图片,分别设为（qrColor）（qrBgColor）两色
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                image.setRGB(x, y, bm.get(x, y) ? qrColor : qrBgColor);
            }
        }
        return image;
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageBaseAndTitle(String data, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return addQrCodeName(getBufferedImageBase(data, width, height, qrColor, qrBgColor), null, null, data,
            title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @return
     * @throws Exception
     */
    public static byte[] getBytesBase(String data) throws Exception {
        return getBytesBase(data, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBaseAndTitle(String data, String title) throws Exception {
        return getBytesBaseAndTitle(data, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @return
     * @throws Exception
     */
    public static byte[] getBytesBase(String data, String suffix) throws Exception {
        return getBytesBase(data, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBaseAndTitle(String data, String suffix, String title) throws Exception {
        return getBytesBaseAndTitle(data, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static byte[] getBytesBase(String data, int width, int height) throws Exception {
        return getBytesBase(data, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBaseAndTitle(String data, int width, int height, String title) throws Exception {
        return getBytesBaseAndTitle(data, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static byte[] getBytesBase(String data, String suffix, int width, int height) throws Exception {
        return getBytesBase(data, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBaseAndTitle(String data, String suffix, int width, int height, String title)
        throws Exception {
        return getBytesBaseAndTitle(data, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesBaseAndColor(String data, int qrColor, int qrBgColor) throws Exception {
        return getBytesBase(data, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor,
            qrBgColor);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBaseAndTitleAndColor(String data, int qrColor, int qrBgColor, String title)
        throws Exception {
        return getBytesBaseAndTitle(data, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            qrColor, qrBgColor, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesBaseAndColor(String data, String suffix, int qrColor, int qrBgColor)
        throws Exception {
        return getBytesBase(data, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBaseAndTitleAndColor(String data, String suffix, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getBytesBaseAndTitle(data, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesBase(String data, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        return getBytesBase(Constant.GENERATE_IMG_SUFFIX,
            getBufferedImageBase(data, width, height, qrColor, qrBgColor));
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBaseAndTitle(String data, int width, int height, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getBytesBase(Constant.GENERATE_IMG_SUFFIX,
            getBufferedImageBaseAndTitle(data, width, height, qrColor, qrBgColor, title));
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesBase(String data, String suffix, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        return getBytesBase(suffix, getBufferedImageBase(data, width, height, qrColor, qrBgColor));
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBaseAndTitle(String data, String suffix, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBytesBase(suffix, getBufferedImageBaseAndTitle(data, width, height, qrColor, qrBgColor, title));
    }

    /**
     * 获取基础的二维码
     * 
     * @param suffix 二维码图片的格式
     * @param bufferedImage 基础的二维码
     * @return
     * @throws Exception
     */
    private static byte[] getBytesBase(String suffix, BufferedImage bufferedImage) throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = null;
        byte[] byteArray = null;

        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, suffix, byteArrayOutputStream);
            byteArray = byteArrayOutputStream.toByteArray();
        } finally {
            closeStream(byteArrayOutputStream);
        }

        return byteArray;
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamBase(String data) throws Exception {
        return getInputStreamBase(data, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBaseAndTitle(String data, String title) throws Exception {
        return getInputStreamBaseAndTitle(data, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH,
            QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamBase(String data, String suffix) throws Exception {
        return getInputStreamBase(data, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBaseAndTitle(String data, String suffix, String title)
        throws Exception {
        return getInputStreamBaseAndTitle(data, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamBase(String data, int width, int height) throws Exception {
        return getInputStreamBase(data, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBaseAndTitle(String data, int width, int height, String title)
        throws Exception {
        return getInputStreamBaseAndTitle(data, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamBase(String data, String suffix, int width, int height)
        throws Exception {
        return getInputStreamBase(data, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBaseAndTitle(String data, String suffix, int width, int height,
        String title) throws Exception {
        return getInputStreamBaseAndTitle(data, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamBaseAndColor(String data, int qrColor, int qrBgColor) throws Exception {
        return getInputStreamBase(data, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            qrColor, qrBgColor);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBaseAndTitleAndColor(String data, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getInputStreamBaseAndTitle(data, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH,
            QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamBaseAndColor(String data, String suffix, int qrColor, int qrBgColor)
        throws Exception {
        return getInputStreamBase(data, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBaseAndTitleAndColor(String data, String suffix, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getInputStreamBaseAndTitle(data, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor,
            qrBgColor, title);
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamBase(String data, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        return getInputStreamBase(Constant.GENERATE_IMG_SUFFIX,
            getBufferedImageBase(data, width, height, qrColor, qrBgColor));
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBaseAndTitle(String data, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getInputStreamBase(Constant.GENERATE_IMG_SUFFIX,
            getBufferedImageBaseAndTitle(data, width, height, qrColor, qrBgColor, title));
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamBase(String data, String suffix, int width, int height, int qrColor,
        int qrBgColor) throws Exception {
        return getInputStreamBase(suffix, getBufferedImageBase(data, width, height, qrColor, qrBgColor));
    }

    /**
     * 获取基础的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBaseAndTitle(String data, String suffix, int width, int height,
        int qrColor, int qrBgColor, String title) throws Exception {
        return getInputStreamBase(suffix,
            getBufferedImageBaseAndTitle(data, width, height, qrColor, qrBgColor, title));
    }

    /**
     * 获取基础的二维码
     * 
     * @param suffix 二维码图片的格式
     * @param bufferedImage 基础的二维码
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamBase(String suffix, BufferedImage bufferedImage) throws Exception {
        return new ByteArrayInputStream(getBytesBase(suffix, bufferedImage));
    }

    /**************************************************************************************************************/
    /**************************************************************************************************************/
    /**************************************************************************************************************/
    /**************************************************************************************************************/
    /**************************************************************************************************************/

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data) throws Exception {
        return getBufferedImage(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BORDER_WIDTH);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data, InputStream logo) throws Exception {
        return getBufferedImage(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BORDER_WIDTH);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data, byte[] logo) throws Exception {
        return getBufferedImage(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BORDER_WIDTH);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, String title) throws Exception {
        return getBufferedImageAndTitle(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, InputStream logo, String title)
        throws Exception {
        return getBufferedImageAndTitle(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, byte[] logo, String title) throws Exception {
        return getBufferedImageAndTitle(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data, int width, int height) throws Exception {
        return getBufferedImage(data, logo, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data, InputStream logo, int width, int height)
        throws Exception {
        return getBufferedImage(data, logo, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data, byte[] logo, int width, int height) throws Exception {
        return getBufferedImage(data, logo, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, int width, int height, String title)
        throws Exception {
        return getBufferedImageAndTitle(data, logo, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, InputStream logo, int width, int height,
        String title) throws Exception {
        return getBufferedImageAndTitle(data, logo, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, byte[] logo, int width, int height,
        String title) throws Exception {
        return getBufferedImageAndTitle(data, logo, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImageAndColor(String data, int qrColor, int qrBgColor) throws Exception {
        return getBufferedImage(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImageAndColor(String data, InputStream logo, int qrColor, int qrBgColor)
        throws Exception {
        return getBufferedImage(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImageAndColor(String data, byte[] logo, int qrColor, int qrBgColor)
        throws Exception {
        return getBufferedImage(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitleAndColor(String data, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getBufferedImageAndTitle(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitleAndColor(String data, InputStream logo, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBufferedImageAndTitle(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitleAndColor(String data, byte[] logo, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBufferedImageAndTitle(data, logo, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        return getBufferedImage(data, logo, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data, InputStream logo, int width, int height, int qrColor,
        int qrBgColor) throws Exception {
        BufferedImage bufferedImageBase = getBufferedImageBase(data, width, height, qrColor, qrBgColor);
        addQrCodeLogo(bufferedImageBase, logo);
        return bufferedImageBase;
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static BufferedImage getBufferedImage(String data, byte[] logo, int width, int height, int qrColor,
        int qrBgColor) throws Exception {
        return getBufferedImage(data, byteToInputStream(logo), width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBufferedImageAndTitle(data, logo, width, height, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, InputStream logo, int width, int height,
        int qrColor, int qrBgColor, String title) throws Exception {

        BufferedImage bufferedImageBaseAndTitle =
            getBufferedImageBaseAndTitle(data, width, height, qrColor, qrBgColor, title);
        addQrCodeLogo(bufferedImageBaseAndTitle, logo);

        return bufferedImageBaseAndTitle;
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static BufferedImage getBufferedImageAndTitle(String data, byte[] logo, int width, int height,
        int qrColor, int qrBgColor, String title) throws Exception {
        return getBufferedImageAndTitle(data, byteToInputStream(logo), width, height, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, InputStream logo) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, byte[] logo) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, InputStream logo, String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, byte[] logo, String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, String suffix) throws Exception {
        return getBytes(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, InputStream logo, String suffix) throws Exception {
        return getBytes(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, byte[] logo, String suffix) throws Exception {
        return getBytes(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, String suffix, String title) throws Exception {
        return getBytesAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, InputStream logo, String suffix, String title)
        throws Exception {
        return getBytesAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, byte[] logo, String suffix, String title) throws Exception {
        return getBytesAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, int width, int height) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, InputStream logo, int width, int height) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, byte[] logo, int width, int height) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, int width, int height, String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, InputStream logo, int width, int height, String title)
        throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, byte[] logo, int width, int height, String title)
        throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, String suffix, int width, int height) throws Exception {
        return getBytes(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, InputStream logo, String suffix, int width, int height)
        throws Exception {
        return getBytes(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, byte[] logo, String suffix, int width, int height) throws Exception {
        return getBytes(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, String suffix, int width, int height, String title)
        throws Exception {
        return getBytesAndTitle(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, InputStream logo, String suffix, int width, int height,
        String title) throws Exception {
        return getBytesAndTitle(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, byte[] logo, String suffix, int width, int height,
        String title) throws Exception {
        return getBytesAndTitle(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesAndColor(String data, int qrColor, int qrBgColor) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor,
            qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesAndColor(String data, InputStream logo, int qrColor, int qrBgColor)
        throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor,
            qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesAndColor(String data, byte[] logo, int qrColor, int qrBgColor) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor,
            qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitleAndColor(String data, int qrColor, int qrBgColor, String title)
        throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitleAndColor(String data, InputStream logo, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitleAndColor(String data, byte[] logo, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesAndColor(String data, String suffix, int qrColor, int qrBgColor) throws Exception {
        return getBytes(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesAndColor(String data, InputStream logo, String suffix, int qrColor, int qrBgColor)
        throws Exception {
        return getBytes(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytesAndColor(String data, byte[] logo, String suffix, int qrColor, int qrBgColor)
        throws Exception {
        return getBytes(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitleAndColor(String data, String suffix, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getBytesAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitleAndColor(String data, InputStream logo, String suffix, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBytesAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitleAndColor(String data, byte[] logo, String suffix, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBytesAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, int width, int height, int qrColor, int qrBgColor) throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, InputStream logo, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, byte[] logo, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        return getBytes(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, int width, int height, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, InputStream logo, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, byte[] logo, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBytesAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, String suffix, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        return getBytes(data, logo, suffix, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, InputStream logo, String suffix, int width, int height, int qrColor,
        int qrBgColor) throws Exception {
        return getBytes(suffix, getBufferedImage(data, logo, width, height, qrColor, qrBgColor));
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String data, byte[] logo, String suffix, int width, int height, int qrColor,
        int qrBgColor) throws Exception {
        return getBytes(data, byteToInputStream(logo), suffix, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, String suffix, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getBytesAndTitle(data, logo, suffix, width, height, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, InputStream logo, String suffix, int width, int height,
        int qrColor, int qrBgColor, String title) throws Exception {
        return getBytes(suffix, getBufferedImageAndTitle(data, logo, width, height, qrColor, qrBgColor, title));
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static byte[] getBytesAndTitle(String data, byte[] logo, String suffix, int width, int height,
        int qrColor, int qrBgColor, String title) throws Exception {
        return getBytesAndTitle(data, byteToInputStream(logo), suffix, width, height, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param suffix 二维码图片的格式
     * @param bufferedImage 标准的二维码
     * @return
     * @throws Exception
     */
    private static byte[] getBytes(String suffix, BufferedImage bufferedImage) throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = null;
        byte[] byteArray = null;

        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, suffix, byteArrayOutputStream);
            byteArray = byteArrayOutputStream.toByteArray();
        } finally {
            closeStream(byteArrayOutputStream);
        }

        return byteArray;
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, InputStream logo) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, byte[] logo) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH,
            QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, InputStream logo, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH,
            QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, byte[] logo, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH,
            QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, String suffix) throws Exception {
        return getInputStream(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, InputStream logo, String suffix) throws Exception {
        return getInputStream(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, byte[] logo, String suffix) throws Exception {
        return getInputStream(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, String suffix, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, InputStream logo, String suffix, String title)
        throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, byte[] logo, String suffix, String title)
        throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, int width, int height) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, InputStream logo, int width, int height) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, byte[] logo, int width, int height) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, int width, int height, String title)
        throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, InputStream logo, int width, int height,
        String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, byte[] logo, int width, int height, String title)
        throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, QrCodeUtil.QR_COLOR,
            QrCodeUtil.QR_BGCOLOR, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, String suffix, int width, int height) throws Exception {
        return getInputStream(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, InputStream logo, String suffix, int width, int height)
        throws Exception {
        return getInputStream(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, byte[] logo, String suffix, int width, int height)
        throws Exception {
        return getInputStream(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, String suffix, int width, int height,
        String title) throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, InputStream logo, String suffix, int width,
        int height, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, byte[] logo, String suffix, int width, int height,
        String title) throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, width, height, QrCodeUtil.QR_COLOR, QrCodeUtil.QR_BGCOLOR,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamAndColor(String data, int qrColor, int qrBgColor) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamAndColor(String data, InputStream logo, int qrColor, int qrBgColor)
        throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamAndColor(String data, byte[] logo, int qrColor, int qrBgColor)
        throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT,
            qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitleAndColor(String data, int qrColor, int qrBgColor, String title)
        throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH,
            QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitleAndColor(String data, InputStream logo, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH,
            QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitleAndColor(String data, byte[] logo, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, QrCodeUtil.QR_WIDTH,
            QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamAndColor(String data, String suffix, int qrColor, int qrBgColor)
        throws Exception {
        return getInputStream(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamAndColor(String data, InputStream logo, String suffix, int qrColor,
        int qrBgColor) throws Exception {
        return getInputStream(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStreamAndColor(String data, byte[] logo, String suffix, int qrColor,
        int qrBgColor) throws Exception {
        return getInputStream(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitleAndColor(String data, String suffix, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor,
            qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitleAndColor(String data, InputStream logo, String suffix,
        int qrColor, int qrBgColor, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor,
            qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitleAndColor(String data, byte[] logo, String suffix, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, QrCodeUtil.QR_WIDTH, QrCodeUtil.QR_HEIGHT, qrColor,
            qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, int width, int height, int qrColor, int qrBgColor)
        throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, InputStream logo, int width, int height, int qrColor,
        int qrBgColor) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, byte[] logo, int width, int height, int qrColor,
        int qrBgColor) throws Exception {
        return getInputStream(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, int width, int height, int qrColor, int qrBgColor,
        String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, InputStream logo, int width, int height,
        int qrColor, int qrBgColor, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, byte[] logo, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, Constant.GENERATE_IMG_SUFFIX, width, height, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, String suffix, int width, int height, int qrColor,
        int qrBgColor) throws Exception {
        return getInputStream(data, logo, suffix, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, InputStream logo, String suffix, int width, int height,
        int qrColor, int qrBgColor) throws Exception {
        return getInputStream(suffix, getBufferedImage(data, logo, width, height, qrColor, qrBgColor));
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String data, byte[] logo, String suffix, int width, int height,
        int qrColor, int qrBgColor) throws Exception {
        return getInputStream(data, byteToInputStream(logo), suffix, width, height, qrColor, qrBgColor);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, String suffix, int width, int height, int qrColor,
        int qrBgColor, String title) throws Exception {
        return getInputStreamAndTitle(data, logo, suffix, width, height, qrColor, qrBgColor, title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, InputStream logo, String suffix, int width,
        int height, int qrColor, int qrBgColor, String title) throws Exception {
        return getInputStream(suffix,
            getBufferedImageAndTitle(data, logo, width, height, qrColor, qrBgColor, title));
    }

    /**
     * 获取标准的二维码
     * 
     * @param data 二维码的内容
     * @param logo 二维码的logo
     * @param suffix 二维码图片的格式
     * @param width 二维码的宽度
     * @param height 二维码的高度
     * @param qrColor 二维码的颜色
     * @param qrBgColor 二维码的背景颜色
     * @param title 二维码的标题
     * @return
     * @throws Exception
     */
    private static InputStream getInputStreamAndTitle(String data, byte[] logo, String suffix, int width, int height,
        int qrColor, int qrBgColor, String title) throws Exception {
        return getInputStreamAndTitle(data, byteToInputStream(logo), suffix, width, height, qrColor, qrBgColor,
            title);
    }

    /**
     * 获取标准的二维码
     * 
     * @param suffix 二维码图片的格式
     * @param bufferedImage 标准的二维码
     * @return
     * @throws Exception
     */
    private static InputStream getInputStream(String suffix, BufferedImage bufferedImage) throws Exception {
        return new ByteArrayInputStream(getBytes(suffix, bufferedImage));
    }

    /**
     * 设置二维码的基础信息
     * 
     * @return
     */
    public static Map<EncodeHintType, Object> getDecodeHintType() {
        // 用于设置QR二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>(5);
        // 设置QR二维码的纠错级别（H为最高级别）具体级别信息
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 设置编码方式
        hints.put(EncodeHintType.CHARACTER_SET, Constant.DEFAULT_ENCODING);
        // 二维码的边框宽度,值越大边框越宽
        hints.put(EncodeHintType.MARGIN, QR_BORDER_WIDTH);
        return hints;
    }

    /**
     * 给二维码图片添加Logo
     * @param image 已经生成好原生的二维码图片
     * @param logo 二维码的logo
     * @param logoConfig logo的基本参数
     * @throws IOException 
     */
    private static void addQrCodeLogo(BufferedImage image, InputStream logoPic) throws IOException {
        Graphics2D g = null;

        try {
            // 读取二维码图片,并构建绘图对象
            g = image.createGraphics();
            // 读取logo图片
            BufferedImage logo = inputStreamToBufferedImage(logoPic);

            // 设置logo的大小(不能超过二维码一定比例的最大值)
            int widthLogo = logo.getWidth() > image.getWidth() * QR_LOGO_RATIO_WIDTH / 100
                ? (image.getWidth() * QR_LOGO_RATIO_WIDTH / 100) : logo.getWidth();
            int heightLogo = logo.getHeight() > image.getHeight() * QR_LOGO_RATIO_HEIGHT / 100
                ? (image.getHeight() * QR_LOGO_RATIO_HEIGHT / 100) : logo.getWidth();

            // logo 放在中心
            int x = (image.getWidth() - widthLogo) / 2;
            int y = (image.getHeight() - heightLogo) / 2;
            // logo放在右下角 int x = (image.getWidth() - widthLogo); int y = (image.getHeight() - heightLogo);

            // 开始绘制图片
            g.drawImage(logo, x, y, widthLogo, heightLogo, null);
            // g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
            // g.setStroke(new BasicStroke(logoConfig.getBorder()));
            // g.setColor(logoConfig.getBorderColor());
            // g.drawRect(x, y, widthLogo, heightLogo);

            logo.flush();
            image.flush();
        } finally {
            g.dispose();
        }
    }

    /**
     * 给二维码图片添加Logo
     * @param bim已经生成好原生的二维码图片
     * @param logo 二维码的logo
     * @param logoConfig logo的基本参数
     * @param productName 要输入的文字
     * @param filename 文件生成的地址
     * @throws IOException 
     */
    private static BufferedImage addQrCodeName(BufferedImage image, InputStream logoPic, LogoConfig logoConfig,
        String productName, String filename) throws IOException {
        try {
            /**
             * 读取二维码图片,并构建绘图对象
             */
            Graphics2D g = image.createGraphics();
            /**
             * 读取logo图片
             */
            BufferedImage logo = inputStreamToBufferedImage(logoPic);

            /**
             * 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码
             */
            int widthLogo =
                logo.getWidth(null) > image.getWidth() * 3 / 10 ? (image.getWidth() * 3 / 10) : logo.getWidth(null),
                heightLogo = logo.getHeight(null) > image.getHeight() * 3 / 10 ? (image.getHeight() * 3 / 10)
                    : logo.getWidth(null);
            /**
             * logo 放在中心
             */
            int x = (image.getWidth() - widthLogo) / 2;
            int y = (image.getHeight() - heightLogo) / 2;
            /**
             * logo放在右下角 int x = (image.getWidth() - widthLogo); int y = (image.getHeight()
             * - heightLogo);
             */
            // 开始绘制图片
            g.drawImage(logo, x, y, widthLogo, heightLogo, null);
            // g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
            // g.setStroke(new BasicStroke(logoConfig.getBorder()));
            // g.setColor(logoConfig.getBorderColor());
            // g.drawRect(x, y, widthLogo, heightLogo);
            g.dispose();
            // 把商品名称添加上去,商品名称不要太长,这里最多支持两行。太长就会自动截取
            if (productName != null && !productName.equals("")) {
                // 新的图片,把带logo的二维码下面加上文字
                BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
                Graphics2D outg = outImage.createGraphics();
                // 画二维码到新的面板
                outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
                // 画文字到新的面板
                outg.setColor(Color.BLACK);
                // 字体、字型、字号
                outg.setFont(new Font("宋体", Font.BOLD, 30));
                // 获取文字总宽度
                int strWidth = outg.getFontMetrics().stringWidth(productName);
                if (strWidth > image.getWidth() - 1) {
                    // 长度过长就截取前面部分
                    outg.drawString(productName, 0,
                        image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 + 5);
                    // 长度过长就换行
                    String productName1 = productName.substring(0, productName.length() / 2);
                    String productName2 = productName.substring(productName.length() / 2, productName.length());
                    int strWidth1 = outg.getFontMetrics().stringWidth(productName1);
                    int strWidth2 = outg.getFontMetrics().stringWidth(productName2);
                    outg.drawString(productName1, 200 - strWidth1 / 2,
                        image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 + 12);
                    BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
                    Graphics2D outg2 = outImage2.createGraphics();
                    outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
                    outg2.setColor(Color.BLACK);
                    // 字体、字型、字号
                    outg2.setFont(new Font("宋体", Font.BOLD, 30));
                    outg2.drawString(productName2, 200 - strWidth2 / 2,
                        outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight()) / 2 + 5);
                    outg2.dispose();
                    outImage2.flush();
                    outImage = outImage2;
                } else {
                    // 画文字
                    outg.drawString(productName, 200 - strWidth / 2,
                        image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 + 12);
                }
                outg.dispose();
                outImage.flush();
                image = outImage;
            }
            logo.flush();
            image.flush();
            ByteArrayOutputStream baos = null;
            try {
                baos = new ByteArrayOutputStream();
                baos.flush();
                ImageIO.write(image, "png", baos);
                // 二维码生成的路径,但是实际项目中,我们是把这生成的二维码显示到界面上的,因此下面的折行代码可以注释掉
                File filepath = new File("D:\\images\\qrcode\\" + filename);
                ImageIO.write(image, "png", filepath);
            } finally {
                try {
                    baos.close();
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
            // return "http://127.0.0.1/qrcode/images/"+filename;
            return null;
            // return image;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 判断一个对象是否不是空(空对象)
     * 
     * @param obj
     * @return
     */
    private static boolean isBlankObject(Object obj) {
        return StringUtil.isBlankObject(obj);
    }

    /**
     * 关闭字节输出流
     * 
     * @param outputStream 需要关闭的字节输出流
     * @throws IOException
     */
    private static void closeStream(OutputStream outputStream) throws IOException {
        FileUtil.closeStream(outputStream);
    }

    /**
     * 将InputStream转为byte[]
     * 
     * @param inputStream
     * @return
     * @throws IOException
     */
    private static byte[] inputStreamToByte(InputStream inputStream) throws IOException {
        return FileUtil.inputStreamToByte(inputStream);
    }

    /**
     * 将byte[]转为InputStream
     * 
     * @param bytes
     * @return
     * @throws IOException
     */
    private static InputStream byteToInputStream(byte[] bytes) throws IOException {
        return FileUtil.byteToInputStream(bytes);
    }

    /**
     * 将InputStream转为BufferedImage
     * 
     * @param inputStream
     * @return
     * @throws IOException
     */
    private static BufferedImage inputStreamToBufferedImage(InputStream inputStream) throws IOException {
        return FileUtil.inputStreamToBufferedImage(inputStream);
    }

    /**
     * 从缓存中获取值
     * 
     * @param <T>
     * @param key
     * @return
     * @throws IOException
     */
    private static <T> T get(String key) throws IOException {
        return CacheUtil.get(key);
    }
}

class LogoConfig {

    /** logo大小(默认为照片的1/5) */
    public static final int DEFAULT_LOGOPART = 5;
    /** logo边框宽度(默认为2) */
    private final int border = 2;
    /** logo边框颜色(默认为白色) */
    private final Color borderColor;
    private int logoPart;

    public LogoConfig() {
        this(Color.WHITE, 0);
    }

    public LogoConfig(Color borderColor, int logoPart) {
        this.logoPart = 0;
        this.borderColor = borderColor;
        this.logoPart = logoPart;
    }

    public int getLogoPart() {
        return logoPart;
    }

    public void setLogoPart(int logoPart) {
        this.logoPart = logoPart;
    }

    /**
     * 获取logo边框宽度(默认为2)
     * 
     * @return
     */
    public int getBorder() {
        return border;
    }

    /**
     * 获取logo边框颜色(默认为白色)
     * 
     * @return
     */
    public Color getBorderColor() {
        return borderColor;
    }

}